import { ValidationError, validate, ValidationArguments, ValidationOptions, registerDecorator } from "class-validator";
import { ClassConstructor, plainToClass } from "class-transformer";

export abstract class BaseEntity {
  /**
   * 验证该对象
   * @param skipMissing 是否跳过为空的属性验证
   * @returns
   */
  public async validateThis(skipMissing = true): Promise<string[]> {
    const result: string[] = [];
    const getErrorMsg = (errors: ValidationError[]) => {
      for (const item of errors) {
        if (item.constraints) {
          const temp = errors.map((e) => Object.values(e.constraints!));
          temp.forEach((t) => {
            result.push(...t);
          });
        }

        if (item.children && item.children.length > 0) {
          getErrorMsg(item.children);
        }
      }
    };

    const errors = await validate(this, {
      skipMissingProperties: skipMissing,
    });

    getErrorMsg(errors);

    return result;
  }

  /**
   * 平面对象转class
   */
  protected static baseTransform<T>(cls: ClassConstructor<T>, plainObject: object): T {
    if (plainObject instanceof cls) {
      return plainObject;
    }
    return plainToClass(cls, plainObject);
  }
}

export function DefaultValue(property: any, validationOptions?: ValidationOptions) {
  return function (object: Object, propertyName: string) {
    registerDecorator({
      name: "defaultValue",
      target: object.constructor,
      propertyName: propertyName,
      constraints: [property],
      options: validationOptions,
      validator: {
        validate(value: any, { object }: ValidationArguments) {
          if (!value) {
            object[propertyName] = property;
          }
          return true;
        },
      },
    });
  };
}
